%%  端点检测程序（用数据差分分割）
%     作者：st
%     时间 : 2019.05.16

%% 格式
% 
%输入数据：
%   data：采集的数据，前几行是n通道的，倒数第2行是时间，倒数第1个行是标签；
%      数据有活动段有休息段
%   fs：采样率
%   numAction：该段数据有效动作数（不包含休息的动作数）
%
%输出数据：
%   returnData = 活动段的起始点和终止点
%

%程序内可调的参数
%mean_threshold：这是阈值的系数
%coordinates_jump：两个肌电动作的活动段之间距离至少为多少

function returnData = Endpoint_detection(data, fs, numAction)
    [m, n] = size(data);                   %m是数据的通道数+标签行    n是每个通道数据点个数
   % m = m - 2;                               %后两行不属于肌电数据
    returnData = [];                        %返回的数据局矩阵
    diff_Data = zeros(1, n - 1);        %通道的变化总和
    
    for i = 1 : m                             %求几个连续点值变化的（每个通道都要处理），并将几个通道的数据加在一起
        a = abs(diff(data(i, :)));
        diff_Data = diff_Data +  a;
    end
    diff_mean = mean(diff_Data);            %计算差异值的平均值
    
    % 滤波器参数和阈值参数，可根据实际值进行修改
    mean_threshold = 1.0;
    jump_value = 2000;                % 两个肌电段之间要至少大于2000个点
    merge_value = 0.1 * fs;           %肌电活动段必须要持续的时间
    
    f = smooth(diff_Data, 50);                         % 窗口为50的平滑
    
    
    %g第一列表示：根据数据矩阵（所有通道）变化值   >  阈值    的位置；
    %   f = [3 5 2 6];  mean_threshold * diff_mean = 4;
    %   g(:, 1) = [2 4]
        
    %g第二列表示：大于阈值的数据连续性（大于1就不是连续的了）
    
    %h表示：在大于阈值的数据中 不连续点超过2000 的位置
    g = [];
    g(:, 1) = find(f > mean_threshold * diff_mean);    % 获取所有大于mean_threshold倍均值的数据坐标 g第一列里保存的索引
    g(2:end, 2) = diff(g(:, 1));           % 第二列相邻索引是否是连续的
    h = find(g(:, 2) > jump_value);      % 索引 找到坐标跳跃值大于阈值的地方，大于阈值即标明为两个动作
    
    
    %% 获取分段点
                   % h_len == 2，那么可以得到3   {len_h+1  }个区间,6   {  2*(len_h + 1)  }个点
                  % h_len == 3，那么可以得到4个区间,8个点
                  % h_len == 4，那么可以得到5个区间,10个点；
    h_len = length(h);
    returnData1 = zeros(1, 2*(h_len));  % 变化大的数据点 [起始点 终止点]
    
   for cnt = 1 : (h_len + 1)                %returnData1仍是索引 
        if cnt == 1
            returnData1(2*cnt - 1) = g(1, 1);
            returnData1(2*cnt) = g(h(cnt) - 1, 1);            
        elseif cnt == h_len + 1
            returnData1(2*cnt - 1) = g(h(cnt - 1), 1);
            returnData1(2*cnt) = g(end, 1);
        else
            returnData1(2*cnt - 1) = g(h(cnt - 1), 1);
            returnData1(2*cnt) = g(h(cnt) - 1,1);
        end
    end
    
    %% 消除干扰点(两个间隔比较小)
    cnt1 = 0;
    returnData2 = [];
    for cnt = 1 : (h_len +1)
        if returnData1(2 * cnt) - returnData1(2 * cnt - 1) > 0.1 * fs            % 设置一个间隔阈值,0.1*Fs,活动段至少持续时间
            cnt1 = cnt1 +1;
            returnData2(2 * cnt1-1) = returnData1(2 * cnt-1);
            returnData2(2 * cnt1) = returnData1(2 * cnt);
        end   
    end                 % returnData2 活动段起始和结束
    
    %% 画图，displayFlag==1， 画出分割图；displayFlag==0， 屏蔽；
    displayFlag = 1;
    if displayFlag
        [m, n] = size(data(1 : 4, :));  %画四个通道的
        maxdata = max(max(data(1 : 4, :)));
        figure;
        
        for cnt = 1:m
            plot(data(cnt,:) + (cnt - 1) * maxdata);  % 通道数从大到小向下排列
            hold on;
        end
        
        for cnt = 1 : cnt1
            plot([returnData2(2*cnt-1),returnData2(2*cnt-1)],[-maxdata,(m)*maxdata],'Linewidth',3, 'color','r');   %连线，将y1 和 y2连接在一起
            hold on;
            plot([returnData2(2*cnt),returnData2(2*cnt)],[-maxdata,(m)*maxdata],'Linewidth',3, 'color', 'g');
            hold on;
        end
        
        returnData(1) = 200;   %起始由200开始
        returnData= [returnData returnData2];    %return Data格式： [起始点索引 结束点索引 起始点索引 结束点索引 .... ]
        
    end
end


        







